"""
邮件同步辅助方法
用于支持多对多文件夹关系的同步逻辑
"""
import os
import hashlib
import re
from sqlalchemy.orm import Session
from api.model.email import Email
from api.model.email_folder import EmailFolder
from api.utils.helpers import generate_imap_key
from api.utils.logger import get_logger

logger = get_logger("email_sync_helper")
sync_logger = get_logger("sync")


def get_uidvalidity(imap_conn, select_data, original_folder_name: str, decoded_folder_name: str, account_id: int) -> str:
    """
    获取文件夹的UIDVALIDITY
    
    Args:
        imap_conn: IMAP连接对象
        select_data: SELECT命令返回的数据
        original_folder_name: 原始文件夹名（编码后）
        decoded_folder_name: 解码后的文件夹名
        account_id: 账户ID
    
    Returns:
        UIDVALIDITY字符串
    """
    current_uidvalidity = None
    
    # 方法1: 从SELECT响应中解析
    for line in select_data:
        if isinstance(line, bytes):
            line_str = line.decode('utf-8', 'ignore')
            if 'UIDVALIDITY' in line_str:
                match = re.search(r'UIDVALIDITY (\d+)', line_str)
                if match:
                    current_uidvalidity = match.group(1)
                    break
    
    # 方法2: 如果方法1失败，尝试使用STATUS命令
    if not current_uidvalidity:
        try:
            status_result, status_data = imap_conn.status(f'"{original_folder_name}"', '(UIDVALIDITY)')
            if status_result == 'OK' and status_data:
                status_str = status_data[0].decode('utf-8', 'ignore')
                match = re.search(r'UIDVALIDITY (\d+)', status_str)
                if match:
                    current_uidvalidity = match.group(1)
        except Exception as e:
            logger.error(f"通过 STATUS 命令获取 UIDVALIDITY 失败: {e}")
    
    # 方法3: 如果以上方法都失败，使用文件夹名+账户ID的哈希作为稳定标识
    if not current_uidvalidity:
        hash_input = f"{account_id}-{decoded_folder_name}".encode('utf-8')
        folder_hash = hashlib.md5(hash_input).hexdigest()[:8]
        current_uidvalidity = str(int(folder_hash, 16))
    
    return current_uidvalidity


def delete_folder_relations(
    uids_to_delete: set,
    existing_uids_map: dict,
    folder_name: str,
    account_email: str,
    db: Session
):
    """
    删除文件夹关联记录，并清理孤立邮件
    
    Args:
        uids_to_delete: 需要删除的UID集合（bytes）
        existing_uids_map: UID -> EmailFolder 的映射
        folder_name: 文件夹名称
        account_email: 账户邮箱（用于日志）
        db: 数据库会话
    """
    if not uids_to_delete:
        return
    
    # 收集需要检查的邮件ID
    email_ids_to_check = set()
    
    for uid in uids_to_delete:
        email_folder = existing_uids_map.get(uid)
        if email_folder:
            email_ids_to_check.add(email_folder.email_id)
            # 删除关联记录
            db.delete(email_folder)
    
    db.flush()
    
    # 检查并清理孤立邮件（没有任何文件夹关联的邮件）
    orphan_count = 0
    for email_id in email_ids_to_check:
        # 检查该邮件是否还有其他文件夹关联
        remaining_relations = db.query(EmailFolder).filter(
            EmailFolder.email_id == email_id
        ).count()
        
        if remaining_relations == 0:
            # 邮件已成为孤立邮件，删除邮件记录和EML文件
            email_record = db.query(Email).filter(Email.id == email_id).first()
            if email_record:
                # 删除EML文件
                if email_record.eml_path and os.path.exists(email_record.eml_path):
                    try:
                        os.remove(email_record.eml_path)
                    except OSError as e:
                        logger.error(f"删除EML文件失败 {email_record.eml_path}: {e}")
                
                # 删除邮件记录（级联删除会自动删除所有关联）
                db.delete(email_record)
                orphan_count += 1
    
    sync_logger.info(
        f"【{account_email}】文件夹 '{folder_name}': "
        f"删除 {len(uids_to_delete)} 条关联记录，清理 {orphan_count} 封孤立邮件"
    )


def find_or_create_email_by_message_id(
    message_id: str,
    email_account_id: int,
    email_data: dict,
    db: Session
) -> Email:
    """
    基于 Message-ID 查找或创建邮件记录
    
    Args:
        message_id: 邮件的 Message-ID
        email_account_id: 账户ID
        email_data: 邮件数据字典
        db: 数据库会话
    
    Returns:
        Email对象（新建或已存在的）
    """
    # 1. 尝试通过 Message-ID 查找（同一账户下）
    email_record = db.query(Email).filter(
        Email.email_account_id == email_account_id,
        Email.message_id == message_id
    ).first()
    
    if email_record:
        return email_record
    
    # 2. 如果 Message-ID 是生成的，尝试通过 content_hash 查找
    if email_data.get("is_generated_message_id", False):
        content_hash = email_data.get("email_hash") or email_data.get("content_hash")
        if content_hash:
            email_record = db.query(Email).filter(
                Email.email_account_id == email_account_id,
                Email.email_hash == content_hash
            ).first()
            
            if email_record:
                return email_record
    
    # 3. 不存在，创建新邮件记录
    # 注意：folder、uid、uidvalidity 等字段已移至 EmailFolder 关联表
    email_record = Email(
        email_account_id=email_account_id,
        message_id=message_id,
        is_generated_message_id=email_data.get("is_generated_message_id", False),
        email_hash=email_data.get("email_hash") or email_data.get("content_hash"),  # 兼容两种key
        subject=email_data.get("subject", ""),
        sender=email_data.get("sender", ""),
        recipients=email_data.get("recipients", ""),
        cc=email_data.get("cc"),
        bcc=email_data.get("bcc"),
        summary=email_data.get("summary", ""),
        has_attachments=email_data.get("has_attachments", False),
        received_date=email_data.get("received_date"),
        sent_date=email_data.get("sent_date"),
        is_read=email_data.get("is_read", False)
    )
    
    db.add(email_record)
    db.flush()  # 获取 email_id
    
    return email_record


def create_or_update_folder_relation(
    email_id: int,
    email_account_id: int,
    folder_name: str,
    uid: str,
    uidvalidity: str,
    flags: str,
    db: Session
) -> EmailFolder:
    """
    创建或更新邮件-文件夹关联记录
    
    Args:
        email_id: 邮件ID
        email_account_id: 账户ID
        folder_name: 文件夹名称
        uid: 邮件UID
        uidvalidity: UIDVALIDITY
        flags: IMAP FLAGS
        db: 数据库会话
    
    Returns:
        EmailFolder对象
    """
    # 生成 imap_key
    imap_key = generate_imap_key(folder_name, uid, uidvalidity)
    
    # 查找是否已存在关联
    folder_relation = db.query(EmailFolder).filter(
        EmailFolder.email_id == email_id,
        EmailFolder.email_account_id == email_account_id,
        EmailFolder.folder_name == folder_name
    ).first()
    
    if folder_relation:
        # 更新现有关联
        folder_relation.uid = uid
        folder_relation.uidvalidity = uidvalidity
        folder_relation.imap_key = imap_key
        folder_relation.flags = flags
    else:
        # 创建新关联
        folder_relation = EmailFolder(
            email_id=email_id,
            email_account_id=email_account_id,
            folder_name=folder_name,
            uid=uid,
            uidvalidity=uidvalidity,
            imap_key=imap_key,
            flags=flags
        )
        db.add(folder_relation)
    
    db.flush()
    return folder_relation